/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package org.letmeshare.stockkeeper.sale.service;

import java.util.Date;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import org.letmeshare.stockkeeper.PersistenceManager;
import org.letmeshare.stockkeeper.common.Status;
import org.letmeshare.stockkeeper.common.exception.InvalidActionException;
import org.letmeshare.stockkeeper.sale.entities.Bill;
import org.letmeshare.stockkeeper.sale.entities.BillEntry;
import org.letmeshare.stockkeeper.sale.module.BillModule;
import org.letmeshare.stockkeeper.stock.entities.Item;
import org.letmeshare.stockkeeper.stock.entities.Stock;
import org.letmeshare.stockkeeper.stock.module.StockModule;

/**
 *
 * @author gAmE wOrLd
 */
public class SalesService {
    private EntityManager em;
    private BillModule billModule;
    private StockModule stockModule;
    private EntityTransaction txn;
    private Bill currentBill;
    
    public static SalesService getInstance() {
        return new SalesService();
    }
    
    private SalesService() {
        em = PersistenceManager.getEntityManager();
        billModule = BillModule.getInstance(em);
        stockModule = StockModule.getInstance(em);
    }
    
    public Bill newSale() {
        if (txn!=null) {
            txn.rollback();
        }
        txn = em.getTransaction();
        txn.begin();
        currentBill = new Bill();
        currentBill.setBilledOn(new Date());
        currentBill.setStatus(Status.CREATED);
        return currentBill;
    }
    
    public void commitBill() {
        if (txn == null || !txn.isActive()) {
            throw new InvalidActionException("No active purchase");
        }
        currentBill.setStatus(Status.COMMITTED);
        currentBill.validate();
        billModule.commitBill(currentBill);
        txn.commit();
        txn = null;
    }
    
    public void consume(Stock stock, double qty, boolean excludeExclTax) {
        if (txn == null || !txn.isActive()) {
            throw new InvalidActionException("No active purchase");
        }
        if(currentBill.getEntries()!=null){
        for (BillEntry entry : currentBill.getEntries()) {
            if (entry.getItem().equals(stock.getItem())) {
                stockModule.consume(stock.getItem(), qty);
                entry.setQty(entry.getQty()+qty);
                return;
            }
        }}
        BillEntry entry = new BillEntry();
        entry.setItem(stock.getItem());
        entry.setQty(qty);
        entry.setExcludeExclTax(excludeExclTax);
        entry.setBilledRate(stock.getItem().getUnitPrice());
        entry.setExclTax(stock.getItem().getExclusiveTax());
        stockModule.consume(stock.getItem(), qty);
        currentBill.addEntry(entry);
    }
    
    public void cancelBill (Bill bill) {
        if (txn != null && txn.isActive()) {
            txn.rollback();
        }
        txn = null;
        txn = em.getTransaction();
        txn.begin();
        billModule.cancelBill(bill);
        txn.commit();
        txn = null;
    }
    
    public List<Bill> getAllBills() {
        return billModule.getAllBills();
    }
    
    public List<Bill> getAllBillsOnDate(Date date) {
        return billModule.getAllBillsOnDate(date);
    }
    
    public List<Bill> getAllActiveBills() {
        return billModule.getAllActiveBills();
    }
    
    public List<Bill> getActiveBillsOnDate(Date date) {
        return billModule.getActiveBillsOnDate(date);
    }
    
    public List<Bill> getAllCancelledBills() {
        return billModule.getAllCancelledBills();
    }
    
    public List<Bill> getCancelledBillsOnDate(Date date) {
        return billModule.getCancelledBillsOnDate(date);
    }
    
    public List<BillEntry> getAllBillEntriesForItem(Item item) {
        return billModule.getAllBillEntriesForItem(item);
    }
    
    public List<BillEntry> getActiveBillEntriesForItem(Item item) {
        return billModule.getActiveBillEntriesForItem(item);
    }
    
    public List<BillEntry> getCancelledBillEntriesForItem(Item item) {
        return billModule.getCancelledBillEntriesForItem(item);
    }
    public List<Bill> getAllBillsBetween(Date startDate, Date endDate) {
        return billModule.getAllBillsBetween(startDate, endDate);
    }
    
    public List<Bill> getActiveBillsBetween(Date startDate, Date endDate) {
        return billModule.getActiveBillsBetween(startDate, endDate);
    }
    
    public List<Bill> getCancelledBillsBetween(Date startDate, Date endDate) {
        return billModule.getCancelledBillsBetween(startDate, endDate);
    }
    public Bill getBill(String id){
        return billModule.getBill(id);
    }
    
    public List<Stock> getAllStocks(){
        return stockModule.getAllStocks();
    }
    
    public Stock getStockById(String id){
        return stockModule.getStock(id);
    }
}
